package com.hnyfkj.jyindustry.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;

/**
 * 
 * @author admin
 *
 */
/**
 * @program: jyindustry
 * @description:oauth2 json格式化类
 * @author: zl
 * @create: 2020-07-09 18:05
 **/
public class JsonFormatter {

	/**
	 * 通用mapper
	 */
	private static ObjectMapper mapper = new ObjectMapper();

	static {
		final JavaTimeModule javaTimeModule = new JavaTimeModule();
		javaTimeModule.addSerializer(LocalDateTime.class,
				new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
		javaTimeModule.addSerializer(LocalDate.class,
				new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
		javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
		javaTimeModule.addDeserializer(LocalDateTime.class,
				new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
		javaTimeModule.addDeserializer(LocalDate.class,
				new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
		javaTimeModule.addDeserializer(LocalTime.class,
				new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
		// json->bean ,忽略bean中不存在的属性
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		// bean->json ,忽略为null的属性
		mapper.setSerializationInclusion(Include.NON_NULL);
		mapper.registerModule(javaTimeModule);
		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
	}

	/**
	 * @param obj
	 *            待转换的对象
	 * @return String 字符串
	 * @throws JsonProcessingException
	 */
	public static String toString(final Object obj) throws JsonProcessingException {

		if (obj instanceof String) {
			return (String) obj;
		} else if (obj == null) {
			return null;
		} else {
			return mapper.writeValueAsString(obj);
		}
	}

	/**
	 * @param obj
	 *            待转换的对象
	 * @param clazz
	 *            目标对象class
	 * @return Object 目标对象实例
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	public static <T> T toObject(final Object obj, final Class<T> clazz)
			throws JsonParseException, JsonMappingException, IOException {

		if (obj == null) {
			return null;
		} else {
			return mapper.readValue(toString(obj), clazz);
		}
	}

	/**
	 * @param jsonStr
	 *            带转换的字符串
	 * @param clazz
	 *            目标对象
	 * @return List list集合
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> toList(final String jsonStr, final Class<T> clazz)
			throws JsonParseException, JsonMappingException, IOException {

		final List<T> lists = new LinkedList<>();
		final List<Object> list = toObject(jsonStr, List.class);
		if (null != list) {
			for (final Object object : list) {
				final T t = toObject(object, clazz);
				if (null != t) {
					lists.add(t);
				}
			}
		}
		return lists;
	}

	public static <T> List<T> toList(final String jsonStr, final TypeReference<List<T>> typeReference)
			throws JsonParseException, JsonMappingException, IOException {

		final List<T> lists = mapper.readValue(jsonStr, typeReference);
		return lists;
	}

	public static JsonNode toJsonNode(final String jsonStr) throws JsonProcessingException, IOException {

		return mapper.readTree(jsonStr);
	}

}
